package com.hoopchina.ui.home;

import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import com.hoopchina.news.R;
import com.hoopchina.service.NewsService;
import com.hoopchina.util.LogUtils;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

/**
 * GetLocation
 * GPS定位管理
 * 
 * @author Neusoft
 */
public class GetLocation {

    private static final String GOOGLE_MAPS_API_KEY = "abcdefg";
    private String              mCity               = "";
    private String              mProvince           = "";
    private LocationManager     mLocMgr;
    private LocationListener    mLocationListener;
    private Context             mContext;

    public GetLocation( Context context ) {
        LogUtils.d( "construction" );
        mContext = context;
        mCity = mContext.getResources().getString( R.string.app_home_getlocation_defaultcity ); // 北京
        mProvince = mContext.getResources().getString( R.string.app_home_getlocation_defaultcity ); // 北京
        mLocMgr = ( LocationManager ) context.getSystemService( Context.LOCATION_SERVICE );

    }

    private String getBestProvider( LocationManager aLocMgr ) {
        Criteria criteria = new Criteria();
        criteria.setAccuracy( Criteria.ACCURACY_FINE );
        criteria.setAltitudeRequired( false );
        criteria.setBearingRequired( false );
        criteria.setCostAllowed( true );
        criteria.setPowerRequirement( Criteria.POWER_LOW );
        return aLocMgr.getBestProvider( criteria, true );
    }

    public void getLocation( final int aWhat, final Handler aHandler ) {
        LogUtils.d( "in" );

        mLocationListener = new LocationListener() {

            @Override
            public void onStatusChanged( String provider, int status, Bundle extras ) {
                LogUtils.d( provider + " onStatusChanged,status=" + status );
            }

            @Override
            public void onProviderEnabled( String provider ) {
                LogUtils.d( provider + " onProviderEnabled" );
            }

            @Override
            public void onProviderDisabled( String provider ) {
                LogUtils.d( provider + " onProviderDisabled" );
            }

            @Override
            public void onLocationChanged( final Location location ) {
                LogUtils.d( "onLocationChanged" );

                NewsService.getTheadPool( true ).submit( new Runnable() {

                    @Override
                    public void run() {
                        LogUtils.d( "onLocationChanged reverseGeocode" );
                        reverseGeocode( location );
                        Message msg = aHandler.obtainMessage();
                        Bundle data = new Bundle();
                        data.putString( "city", getCity() );
                        data.putString( "province", getProvince() );
                        msg.setData( data );
                        msg.what = aWhat;
                        aHandler.sendMessage( msg );
                        // mLocMgr.removeUpdates( mLocationListener );
                    }
                } );

            }
        };

        String bestProvider = getBestProvider( mLocMgr );
        if ( bestProvider != null && bestProvider.equalsIgnoreCase(LocationManager.NETWORK_PROVIDER)) {
            Location location = mLocMgr.getLastKnownLocation( bestProvider );
            if ( location != null ) {
                LogUtils.d( " getLastKnownLocation, location != null" );
                mLocationListener.onLocationChanged( location );
            }

//            if ( bestProvider.equalsIgnoreCase( LocationManager.GPS_PROVIDER ) ) {
//
//                mLocMgr.requestLocationUpdates( LocationManager.GPS_PROVIDER, 10000, 0,
//                        mLocationListener );
//            }
        }

        mLocMgr.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 30000, 0,
                mLocationListener );

    }

    private void setCity( String aCity ) {
        this.mCity = aCity;
    }

    private void setProvince( String aProvince ) {
        this.mProvince = aProvince;
    }

    public String getCity() {
        return mCity;
    }

    public String getProvince() {
        return mProvince;
    }

    /**
     * 根据location在google地图上获得位置信息
     * 
     * @param loc gps经纬度
     */
    public void reverseGeocode( Location loc ) {
        HttpURLConnection connection = null;
        URL serverAddress = null;
        try {
            serverAddress = new URL( "http://maps.google.com/maps/geo?q="
                    + Double.toString( loc.getLatitude() ) + ","
                    + Double.toString( loc.getLongitude() )
                    + "&output=xml&oe=utf8&sensor=true&key=" + GOOGLE_MAPS_API_KEY );
            connection = null;
            connection = ( HttpURLConnection ) serverAddress.openConnection();
            connection.setRequestMethod( "GET" );
            connection.setDoOutput( true );
            connection.setReadTimeout( 10000 );
            connection.connect();

            try {
                InputStreamReader isr = new InputStreamReader( connection.getInputStream() );
                InputSource source = new InputSource( isr );
                SAXParserFactory factory = SAXParserFactory.newInstance();
                SAXParser parser = factory.newSAXParser();
                XMLReader xr = parser.getXMLReader();
                GoogleReverseGeocodeXmlHandler handler = new GoogleReverseGeocodeXmlHandler();
                xr.setContentHandler( handler );
                xr.parse( source );

                setCity( handler.getLocalityName() );
                setProvince( handler.getProvinceName() );

            }
            catch ( Exception ex ) {
                ex.printStackTrace();
            }
        }
        catch ( Exception ex ) {
            ex.printStackTrace();
        }
    }

    public class GoogleReverseGeocodeXmlHandler extends DefaultHandler {
        private boolean       inLocalityName = false;
        private boolean       inProvinceName = false;
        private boolean       finished       = false;
        private StringBuilder mBuilder;
        private String        mLocalityName;
        private String        mProvinceName;

        public String getProvinceName() {
            return NameParser( this.mProvinceName );
        }

        public String getLocalityName() {
            return NameParser( this.mLocalityName );
        }

        /*
         * 对省市显示进行优化
         */
        private String NameParser( String aTmpName ) {
            if ( aTmpName.contains( "省" ) || aTmpName.contains( "市" ) )
                aTmpName = aTmpName.substring( 0, aTmpName.length() - 1 );
            else {
                if ( aTmpName.contains( "自治区" ) ) {
                    if ( aTmpName.equalsIgnoreCase( "内蒙古自治区" ) )
                        aTmpName = aTmpName.substring( 0, 3 );
                    else
                        aTmpName = aTmpName.substring( 0, 2 );
                }
                else {
                    if ( aTmpName.contains( "地区" ) ) {
                        aTmpName = aTmpName.substring( 0, aTmpName.length() - 2 );
                    }
                    else {
                        if ( aTmpName.contains( "自治州" ) )// 延边
                        {
                            aTmpName = aTmpName.substring( 0, 2 );
                        }
                    }
                }
            }

            return aTmpName;
        }

        @Override
        public void characters( char[] ch, int start, int length ) throws SAXException {
            super.characters( ch, start, length );

            if ( ( this.inProvinceName || this.inLocalityName ) && !this.finished ) {
                if ( ( ch[start] != '\n' ) && ( ch[start] != ' ' ) ) {
                    mBuilder.append( ch, start, length );
                }
            }
        }

        @Override
        public void endElement( String uri, String localName, String name ) throws SAXException {
            super.endElement( uri, localName, name );

            if ( !this.finished ) {
                if ( localName.equalsIgnoreCase( "AdministrativeAreaName" ) ) {
                    this.mProvinceName = mBuilder.toString();
                }
                if ( localName.equalsIgnoreCase( "LocalityName" ) ) {
                    this.mLocalityName = mBuilder.toString();
                    this.finished = true;
                }

                if ( mBuilder != null ) {
                    mBuilder.setLength( 0 );
                }
            }
        }

        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            mBuilder = new StringBuilder();
        }

        @Override
        public void startElement( String uri, String localName, String name, Attributes attributes )
                throws SAXException {
            super.startElement( uri, localName, name, attributes );

            if ( localName.equalsIgnoreCase( "AdministrativeAreaName" ) ) {
                this.inProvinceName = true;
            }
            if ( localName.equalsIgnoreCase( "LocalityName" ) ) {
                this.inLocalityName = true;
            }
        }
    }

    /*
     * 返回信息接口
     */
    public interface Callback {
        public void onGetComplete( String aCurProvince, String aCurCity );

    }
}